﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.Common.Math;
using Buddy.CommonBot;
using Buddy.Navigation;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt.Routines;
using WingIt.Routines.Mirrors;

using Action = Buddy.BehaviorTree.Action;


namespace WingIt
{
    [RevisionControlId("$Id: Casting.cs 684 2012-08-08 10:09:07Z Chinajade $")]
    public static partial class CreateBTPS
    {
        /// <summary>
        /// <para>If DOWHEN evaluates to true, stops the toon from casting.</para>
        /// <para>Notes:<list type="bullet">
        /// <item><description><para> * If DOWHEN is omitted, the behavior will always be attempted.</para></description></item>
        /// <item><description><para> * This method is useful for prematurely terminating a channeled ability.</para></description></item>
        /// <item><description><para> * Failed attempts to stop casting are throttled so other behavior tree actions can take place.
        /// When throttling happens, a message is emitted to the log.</para></description></item>
        /// <item><description><para> * Failure to stop casting can happen due to lag, client stuttering, low frame rates, game terrain, and other things.</para></description></item>
        /// </list></para>
        /// </summary>
        /// <returns><para>a behavior tree Composite for use in a PrioritySelector.</para>
        /// <para>The Composite returns RunStatus.Success to the BT parent if the behavior is in progress.
        /// Otherwise, returns RunStatus.Failure indicating no action was necessary.</para>
        /// </returns>
        ///  7Jul2012-20:27UTC chinajade
        public static Composite StopCasting(CanRunDecoratorDelegate doWhen = null)
        {
            TimeSpan    StopCastingRetryThrottleDuration        = TimeSpan.FromMilliseconds(500);

            doWhen = doWhen ?? (ctx => true);       // Resolve optional argument to something sane

            return new Decorator(whenCastingInProgress => doWhen(whenCastingInProgress) && Me.IsCasting,
                new PrioritySelector(
                    // Throttle attempts...
                    new Decorator(whenNotThrottled => stopCastingRetryThrottle.IsReady(),
                        new Action(stopCastingAndThrottle =>  {
                            stopCastingRetryThrottle.Used(StopCastingRetryThrottleDuration);
                            using(BuddyTor.Memory.AcquireFrame()) {
                                Me.CallScript<bool>(true, "AbilityCancel");
                            }})),

                    // This behavior is not done until we can meet our exit criteria (casting stopped)...
                    // We can get this far in the PrioritySelector, if the behavior was throttled.
                    new Action(alwaysSucceed => { return (RunStatus.Success); })
                    ));
        }
        public static Throttle stopCastingRetryThrottle = new Throttle_Timed("StopCastingRetry");
    }
}
